package tools

import (
	"crypto/tls"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/unrolled/secure"
	"gopkg.in/gomail.v2"
	myjwt "hello/jwt"
	"io/ioutil"
	"log"
	"net/http"
	"strconv"
	"strings"
)

func TlsHandler() gin.HandlerFunc {
	return func(c *gin.Context) {
		secureMiddleware := secure.New(secure.Options{
			SSLRedirect:  true,
			SSLHost:     "localhost:8081",
		})
		err := secureMiddleware.Process(c.Writer, c.Request)

		// If there was an error, do not continue.
		if err != nil {
			return
		}

		c.Next()
	}
}

func Cors() gin.HandlerFunc {
	return func(c *gin.Context) {
		method := c.Request.Method
		origin := c.Request.Header.Get("Origin") //请求头部
		if origin != "" {
			//接收客户端发送的origin （重要！）
			c.Header("Access-Control-Allow-Origin", "*")
			c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE")
			c.Header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization")
			c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Cache-Control, Content-Language, Content-Type")
			c.Header("Access-Control-Allow-Credentials", "true")
		}

		//允许类型校验
		if method == "OPTIONS" {
			c.AbortWithStatus(http.StatusNoContent)
		}

		defer func() {
			if err := recover(); err != nil {
				log.Printf("Panic info is: %v", err)
			}
		}()

		c.Next()
	}
}

func JWTAuthMiddleware(token string) (int, string, string, string, string) {
	// 客户端携带Token有三种方式 1.放在请求头 2.放在请求体 3.放在URI
	// 这里假设Token放在Header的Authorization中，并使用Bearer开头
	// 这里的具体实现方式要依据你的实际业务情况决定
	authHeader := token
	if authHeader == "" { // 如果请求头中没有附带token
		return 404, "未识别到token", "", "", ""
	}
	// 按空格分割
	parts := strings.SplitN(authHeader, " ", 2)
	if !(len(parts) == 2 && parts[0] == "Bearer") {
		return 401, "token格式不正确", "", "", ""
	}
	// parts[1]是获取到的tokenString，我们使用之前定义好的解析JWT的函数来解析它
	mc, err := myjwt.ParseToken(parts[1])
	if err != nil {
		return 401, "无效的token", "", "", ""
	}
	//fmt.Println("userID = " + mc.UserID)
	//fmt.Println("userName = " + mc.Username)
	//fmt.Println("number = " + mc.Number)

	// 将当前请求的username信息保存到请求的上下文c上
	return 500, "success", mc.UserID, mc.Username, mc.Number
}
func SendMail(mailTo []string, subject string, body string) error {
	//定义邮箱服务器连接信息，如果是网易邮箱 pass填密码，qq邮箱填授权码

	//mailConn := map[string]string{
	//  "user": "xxx@163.com",
	//  "pass": "your password",
	//  "host": "smtp.163.com",
	//  "port": "465",
	//}

	mailConn := map[string]string{
		"user": "54535282@qq.com",
		"pass": "niwwbypuiluvbjjj",
		"host": "smtp.qq.com",
		"port": "465",
	}

	port, _ := strconv.Atoi(mailConn["port"]) //转换端口类型为int

	m := gomail.NewMessage()
	//这种方式可以添加别名，即“XX官方”
	//说明：如果是用网易邮箱账号发送，以下方法别名可以是中文，如果是qq企业邮箱，以下方法用中文别名，会报错，需要用上面此方法转码
	//m.SetHeader("From", "FB Sample"+"<"+mailConn["user"]+">") //这种方式可以添加别名，即“FB Sample”， 也可以直接用<code>m.SetHeader("From",mailConn["user"])</code> 读者可以自行实验下效果
	//m.SetHeader("From", mailConn["user"])
	m.SetHeader("From", m.FormatAddress(mailConn["user"], "启明星工作室"))

	m.SetHeader("To", mailTo...)    //发送给多个用户
	m.SetHeader("Subject", subject) //设置邮件主题
	m.SetBody("text/html", body)    //设置邮件正文

	d := gomail.NewDialer(mailConn["host"], port, mailConn["user"], mailConn["pass"])

	err := d.DialAndSend(m)
	return err
}

func HandleSendEmail(mailTo []string, subject string, body string) (int, string) {
	err := SendMail(mailTo, subject, body)
	if err != nil {
		log.Println(err)
		fmt.Println("send failed")
		return 400, "send,failed"
	} else {
		fmt.Println("success")
		return 500, "send success"
	}
}

func SendQQMessage(msg string,group string) (int,string){
	var url string
	//pre := "https://api.day.app/EVmaPw8kS9UNMQdqwPiQei/报名通知/"
	pre := "https://api.kuku.me/bot/sendGroupMsg?"
	token := "3yxxs1os2brrdtuh53lm"
	url = pre + "token="+token+"&msg="+msg+"&qq="+group
	//url = pre + msg
	fmt.Println("url = " + url)
	GetData(url)
	return 500,""
}


func GetData(url string){
	tr := &http.Transport{
		TLSClientConfig:    &tls.Config{InsecureSkipVerify: true}, }  //如果需要测试自签名的证书 这里需要设置跳过证书检测 否则编译报错
	client := &http.Client{Transport: tr}
	resp, err := client.Get(url)

	if err != nil {
		fmt.Println("error:", err)
		return
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	fmt.Println(string(body))
}